/**
* Copyright (c) By zengqh.
*
* This program is just for fun or demo, in the hope that it  
* will be useful, you can redistribute it and/or modify freely.
*
* Time: 2013/05/21
* File: Camera.h
* Blog: http://www.cnblogs.com/zengqh/
**/

#pragma once

#include <math/math.h>
#include <core/Flags.h>

namespace HY
{
class Camera
{
public:
	enum
	{
		PT_ORTHOGRAPHIC,
		PT_PERSPECTIVE
	};

	enum
	{
		DT_VIEW_MATRIX,
		DT_PROJ_MATRIX,
		DT_FRUSTUM
	};

public:
	Camera();
	virtual ~Camera();

	void setNearPlane(float near_clip);
	void setFarPlane(float far_clip);

	void setFov(float fov);

	void setOrthoSize(float othro);

	void setOrthoSize(const Vector2& size);

	void setAspectRatio(float ratio);

	float getNearClip() const;

	float getFarClip() const;

	float getFov() const;

	float getOrthoSize() const;

	float getAspectRatio() const;

	const Frustum& getFrustum() const;

	const Matrix4& getProjMatrix() const;

	const Matrix4& getViewMatrix() const;

	Frustum getSplitFrust(float near_clip, float far_clip);

	Frustum getViewspaceFrustum() const;

	Frustum getViewSpaceSplitFrustum(float near_clip, float far_clip) const;

	Vector2 worldToScreenPoint(const Vector3& worldPos);

	Vector3 screenToWorldPoint(const Vector3& screenPos);

	Vector3 getForwardVector();

	Vector3 getRightVector();

	Vector3 getUpVector();

	float getDistance(const Vector3& worldPos) const;

	float getDistanceSquared(const Vector3& worldPos) const;

	void setTransform(const Vector3& eye, const Vector3& target, const Vector3& up);
	void setTransform(const Matrix4& matWorld);

	void setProjType(uint32 type);
	uint32 getProjType() const;

	bool isPerspective() const;
	bool isOrthographic() const;

protected:
	void makePerspectiveProj();
	void makeOrthoProj();

protected:
	Matrix4				view_matrix_;
	Matrix4				world_matrix_;
	Matrix4				proj_matrix_;
	Frustum				frustum_;
	uint32				proj_type_;
	float				near_clip_;
	float				far_clip_;
	float				fov_;
	float				ortho_size_;
	float				aspect_ratio_;
	Flags32				dirty_flags_;
};
}